from machine import Pin
import time
import network
import socket

def run_web_server():
    # WiFi配置
    ssid = "LAPTOP-D3RPTUAA 6358"
    password = "19234949992.ch"
    
    # 创建LED对象（作为全局变量或类成员）
    global led
    led = Pin(5, Pin.OUT)
    
    # 连接WiFi
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    
    # 等待连接（带超时）
    timeout = 10
    while timeout > 0 and not wlan.isconnected():
        timeout -= 1
        led.on()
        time.sleep(1)
        print(f"等待连接...({timeout}秒)")
    
    if not wlan.isconnected():
        print("WiFi连接超时!")
        led.on()
        return  # 退出函数
    
    print("WiFi连接成功!")
    print(f"IP地址: {wlan.ifconfig()[0]}")
    led.off()  # LED熄灭表示连接成功
    
    # 创建socket对象（作为全局变量）
    global server_socket
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
    server_socket = socket.socket()
    server_socket.bind(addr)
    server_socket.listen(1)
    print('Web服务器已启动，访问: http://' + wlan.ifconfig()[0])
    
    # HTML内容（精简版示意）
    html = """
            <!DOCTYPE html>
            <html lang="zh-CN">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>六足机器人上位机</title>
                <script src="https://cdn.tailwindcss.com"></script>
                <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
                <script>
                    tailwind.config = {
                        theme: {
                            extend: {
                                colors: {
                                    primary: '#165DFF',
                                    secondary: '#36D399',
                                    accent: '#FF6B35',
                                    dark: '#1E293B',
                                    light: '#F8FAFC',
                                    frame: '#E2E8F0',
                                    control: '#FF5722',
                                    radar: '#00FF00',
                                },
                                fontFamily: {
                                    inter: ['Inter', 'system-ui', 'sans-serif'],
                                },
                            }
                        }
                    }
                </script>
                <style type="text/tailwindcss">
                    @layer utilities {
                        .content-auto {
                            content-visibility: auto;
                        }
                        .grid-layout {
                            grid-template-rows: 65% 35%;
                            height: 100%;
                        }
                        .grid-layout-right {
                            grid-template-rows: 50% 50%;
                            height: 100%;
                        }
                        .frame-border {
                            border: 5px solid theme('colors.frame');
                        }
                        .app-height {
                            height: calc(100vh);
                        }
                        .key-button {
                            @apply w-12 h-12 flex items-center justify-center rounded-lg bg-gray-100 text-gray-700 font-medium transition-all duration-200 shadow-sm;
                        }
                        .key-button-active {
                            @apply bg-control text-white transform scale-105 shadow-md;
                        }
                        .robot-arena {
                            @apply relative w-full h-full bg-gray-100 rounded-lg overflow-hidden;
                        }
                        .robot {
                            @apply absolute w-12 h-12 bg-control rounded-full flex items-center justify-center text-white transition-all duration-150 shadow-md;
                        }
                        .keyboard-container {
                            @apply grid grid-cols-3 gap-2 justify-center max-w-[12rem] mx-auto;
                        }
                        .video-container {
                            @apply relative w-full h-full bg-gray-100 rounded-lg overflow-hidden;
                        }
                        .video-placeholder {
                            @apply absolute inset-0 flex flex-col items-center justify-center bg-gray-100;
                        }
                        .sensor-data-container {
                            @apply w-full h-full bg-gray-50 rounded-lg overflow-hidden p-4;
                        }
                        .sensor-grid {
                            @apply grid grid-cols-2 gap-2 h-full;
                        }
                        .sensor-item {
                            @apply bg-white p-2 h-12 rounded-lg shadow-sm flex flex-col justify-center;
                        }
                        .sensor-label {
                            @apply text-xs text-gray-500 mb-1;
                        }
                        .sensor-value {
                            @apply text-lg font-semibold text-dark;
                        }
                        .radar-container {
                            @apply w-full h-full bg-dark rounded-lg overflow-hidden relative;
                        }
                        .radar-controls {
                            @apply absolute top-2 right-2 flex gap-1 z-10;
                        }
                        .radar-control-btn {
                            @apply bg-white/20 hover:bg-white/40 text-white p-1 rounded text-xs transition-colors;
                        }
                    }
                </style>
            </head>
            <body class="font-inter bg-gray-50">
                <!-- 主要内容区 -->
                <div class="relative app-height frame-border overflow-hidden w-full">
                    <!-- 左右分隔线 -->
                    <div class="absolute left-1/2 top-0 bottom-0 w-[5px] bg-frame -ml-[2.5px] z-10"></div>

                    <!-- 左侧区域 -->
                    <div class="absolute left-0 top-0 bottom-0 w-1/2 grid grid-layout">
                        <!-- 左侧上下分隔线 -->
                        <div class="absolute left-0 right-0 top-[65%] h-[5px] bg-frame -mt-[2.5px] z-10"></div>

                        <!-- 左上区域 - ESP32-CAM视频显示 -->
                        <div class="bg-white p-4 overflow-hidden relative">
                            <div class="absolute inset-0 bg-primary/5 z-0"></div>
                            <div class="relative z-10">
                                <h2 class="text-xl font-bold text-dark mb-3 flex items-center">
                                    <i class="fa fa-area-chart text-primary mr-2"></i>
                                    摄像头
                                </h2>

                                <!-- 视频显示区域 -->
                                <div class="video-container">
                                    <!-- 视频占位符，视频加载时显示 -->
                                    <div id="video-placeholder" class="video-placeholder">
                                        <div class="animate-pulse rounded-full h-16 w-16 bg-gray-300 mb-3"></div>
                                        <div class="animate-pulse rounded h-3 w-3/4 bg-gray-300 mb-2"></div>
                                        <div class="animate-pulse rounded h-3 w-1/2 bg-gray-300"></div>
                                        <p class="mt-4 text-gray-500 text-sm" id="video-status-text">正在连接ESP32-CAM...</p>
                                    </div>

                                    <!-- 视频元素 -->
                                    <img id="esp32-cam-video" src="https://picsum.photos/800/600" alt="ESP32-CAM视频流" class="w-full h-80 object-cover hidden">

                                    <!-- 视频控制按钮 -->
                                    <div class="absolute bottom-3 right-3 flex gap-2 z-20">
                                        <button id="refresh-video" class="bg-white/80 hover:bg-white text-primary p-2 rounded-full shadow-md transition-colors">
                                            <i class="fa fa-refresh"></i>
                                        </button>
                                        <button id="fullscreen-video" class="bg-white/80 hover:bg-white text-primary p-2 rounded-full shadow-md transition-colors">
                                            <i class="fa fa-expand"></i>
                                        </button>
                                        <button id="exit-fullscreen" class="bg-white/80 hover:bg-white text-primary p-2 rounded-full shadow-md transition-colors hidden">
                                            <i class="fa fa-compress"></i>
                                        </button>
                                    </div>
                                </div>

                                <!-- 视频状态信息 -->
                                <div class="mt-2 flex justify-between items-center">
                                    <div class="text-xs text-gray-500">
                                        <span id="video-status">状态: <span id="video-status-detail">连接中...</span></span>
                                    </div>
                                </div>
                            </div>
                            <div class="absolute -bottom-3 -right-3 w-16 h-16 bg-primary/10 rounded-full"></div>
                        </div>

                        <!-- 左下区域 - 机器人控制 -->
                        <div class="bg-white p-4 overflow-hidden relative">
                            <div class="absolute inset-0 bg-control/5 z-0"></div>
                            <div class="relative z-10">
                                <h2 class="text-lg font-bold text-dark mb-2 flex items-center">
                                    <i class="fa fa-gamepad text-control mr-2"></i>
                                    机器人控制
                                </h2>

                                <!-- 步态切换按钮区域 -->
                                <div class="absolute top-4 right-4 flex gap-2 z-20">
                                    <button id="gait-wave" class="px-2 py-1 rounded-md text-xs transition-all duration-200 bg-gray-200 text-gray-700 hover:bg-gray-300">
                                        Wave
                                    </button>
                                    <button id="gait-triangle" class="px-2 py-1 rounded-md text-xs transition-all duration-200 bg-control text-white">
                                        Triangle
                                    </button>
                                </div>

                                <!-- 键盘布局 -->
                                <div class="keyboard-container mb-3">
                                    <div class="col-span-3 flex justify-center">
                                        <button id="btn-up" class="key-button text-sm">W</button>
                                    </div>
                                    <div class="col-span-3 grid grid-cols-3 gap-2">
                                        <div class="col-start-1 flex justify-end">
                                            <button id="btn-left" class="key-button text-sm">A</button>
                                        </div>
                                        <div class="flex justify-center">
                                            <button id="btn-down" class="key-button text-sm">S</button>
                                        </div>
                                        <div class="flex justify-start">
                                            <button id="btn-right" class="key-button text-sm">D</button>
                                        </div>
                                    </div>
                                </div>

                                <div class="robot-arena">
                                    <div id="robot" class="robot">
                                        <i class="fa fa-arrow-up"></i>
                                    </div>
                                </div>

                                <div class="mt-2 text-xs text-gray-500 flex flex-wrap gap-x-4">
                                    <div class="w-full sm:w-auto"><span>当前指令:</span> <span id="current-command">等待输入...</span></div>
                                    <div class="w-full sm:w-auto"><span>步态模式:</span> <span id="gait-mode">Triangle</span></div>
                                </div>
                            </div>
                            <div class="absolute -bottom-3 -right-3 w-12 h-12 bg-control/10 rounded-full"></div>
                        </div>
                    </div>

                    <!-- 右侧区域 -->
                    <div class="absolute right-0 top-0 bottom-0 w-1/2 grid grid-layout-right">
                        <!-- 右侧上下分隔线 -->
                        <div class="absolute left-0 right-0 top-1/2 h-[5px] bg-frame -mt-[2.5px] z-10"></div>

                        <!-- 右上区域 - 传感器数据显示 -->
                        <div class="bg-white p-4 overflow-hidden relative">
                            <div class="absolute inset-0 bg-accent/5 z-0"></div>
                            <div class="relative z-10">
                                <h2 class="text-lg font-bold text-dark mb-2 flex items-center">
                                    <i class="fa fa-tachometer text-accent mr-2"></i>
                                    传感器数据
                                </h2>

                                <!-- 传感器数据容器 -->
                                <div class="sensor-data-container">
                                    <div class="sensor-grid">
                                        <!-- 第一列 -->
                                        <div class="sensor-item">
                                            <span class="sensor-label">环境温度</span>
                                            <span class="sensor-value" id="temp-value">25.6°C</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">环境湿度</span>
                                            <span class="sensor-value" id="humidity-value">48.2%</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">纬度</span>
                                            <span class="sensor-value" id="latitude-value">30.1234°</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">经度</span>
                                            <span class="sensor-value" id="longitude-value">120.5678°</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">电池电压</span>
                                            <span class="sensor-value" id="battery-voltage">7.8V</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">电池温度</span>
                                            <span class="sensor-value" id="battery-temp">32.1°C</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">开机时间</span>
                                            <span class="sensor-value" id="uptime-value">02:35:42</span>
                                        </div>
                                        <div class="sensor-item">
                                            <span class="sensor-label">MCU占用</span>
                                            <span class="sensor-value text-green-500" id="system-status">20%</span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="absolute -top-3 -right-3 w-12 h-12 bg-accent/10 rounded-full"></div>
                        </div>

                        <!-- 右下区域 - 360雷达点云图 -->
                        <div class="bg-white p-4 overflow-hidden relative">
                            <div class="absolute inset-0 bg-dark/5 z-0"></div>
                            <div class="relative z-10">
                                <h2 class="text-lg font-bold text-dark mb-2 flex items-center">
                                    <i class="fa fa-rss text-dark mr-2"></i>
                                    360°雷达点云图
                                </h2>

                                <div class="radar-container" id="radar-container">
                                    <!-- 雷达Canvas -->
                                    <canvas id="radar-canvas" width="400" height="275"></canvas>

                                    <!-- 雷达状态 -->
                                    <div class="absolute bottom-2 left-2 text-xs text-white/80">
                                        <span id="radar-status">状态: 初始状态</span>
                                    </div>
                                </div>
                            </div>
                            <div class="absolute -bottom-3 -left-3 w-12 h-12 bg-dark/10 rounded-full"></div>
                        </div>
                    </div>
                </div>

                <script>
                    // 全局数据结构
                    const esp32Data = {
                        isConnected: false, // 新增：连接状态标记
                        videoStream: null,
                        radarPoints: [],
                        robotStatus: {
                            position: { x: 50, y: 50 },
                            direction: 0,
                            gait: 'triangle',
                            radarAngle: -Math.PI / 2 // 初始雷达角度（向上）
                        }
                    };

                    // DOM加载完成后初始化所有功能
                    document.addEventListener('DOMContentLoaded', () => {
                        // 初始化视频流
                        initVideoStream();

                        // 初始化机器人控制（包含按键反馈）
                        initRobotControl();

                        // 初始化雷达点云图
                        setTimeout(initRadar, 100); // 延迟初始化，确保容器尺寸正确

                        // 初始化传感器数据模拟更新
                        initSensorDataSimulation();

                        // 监听窗口大小变化，重新初始化可视化组件
                        window.addEventListener('resize', () => {
                            if (radarCanvas) {
                                resizeRadarCanvas();
                            }
                        });
                    });

                    // ====================== 视频流处理 ======================
                    // 全局变量，用于跟踪全屏状态
                    let isFullscreen = false;

                    // 初始化视频流
                    function initVideoStream() {
                        const videoElement = document.getElementById('esp32-cam-video');
                        const videoPlaceholder = document.getElementById('video-placeholder');
                        const refreshButton = document.getElementById('refresh-video');
                        const fullscreenButton = document.getElementById('fullscreen-video');
                        const exitFullscreenButton = document.getElementById('exit-fullscreen');
                        const videoStatusDetail = document.getElementById('video-status-detail');
                        const videoStatusText = document.getElementById('video-status-text');

                        // 初始状态显示"连接中"
                        videoStatusDetail.textContent = '连接中...';
                        videoStatusText.textContent = '正在连接ESP32-CAM...';

                        // 模拟连接过程（随机成功或失败）
                        const isConnectionSuccessful = Math.random() < 0.1;

                        setTimeout(() => {
                            if (isConnectionSuccessful) {
                                // 连接成功
                                videoPlaceholder.classList.add('hidden');
                                videoElement.classList.remove('hidden');
                                videoStatusDetail.textContent = '连接成功';
                                videoStatusText.textContent = 'ESP32-CAM已连接';
                                esp32Data.isConnected = true;
                            } else {
                                // 连接失败
                                videoStatusDetail.textContent = '连接失败';
                                videoStatusText.textContent = '连接ESP32-CAM超时，请重试';
                                videoStatusText.classList.add('text-red-500');
                                videoElement.classList.remove('hidden');
                                esp32Data.isConnected = false;
                            }
                        }, 3000); // 3秒超时时间

                        // 刷新视频
                        refreshButton.addEventListener('click', () => {
                            videoElement.classList.add('hidden');
                            videoPlaceholder.classList.remove('hidden');
                            videoStatusDetail.textContent = '重新连接...';
                            videoStatusText.textContent = '正在重新连接ESP32-CAM...';
                            videoStatusText.classList.remove('text-red-500');
                            esp32Data.isConnected = false;

                            // 重置连接状态
                            setTimeout(() => {
                                const isReconnectionSuccessful = Math.random() > 0.3;
                                if (isReconnectionSuccessful) {
                                    videoPlaceholder.classList.add('hidden');
                                    videoElement.classList.remove('hidden');
                                    videoStatusDetail.textContent = '连接成功';
                                    videoStatusText.textContent = 'ESP32-CAM已连接';
                                    esp32Data.isConnected = true;
                                } else {
                                    videoStatusDetail.textContent = '连接失败';
                                    videoStatusText.textContent = '重新连接ESP32-CAM超时，请重试';
                                    videoStatusText.classList.add('text-red-500');
                                    videoElement.classList.remove('hidden');
                                    esp32Data.isConnected = false;
                                }
                            }, 3000);
                        });

                        // 全屏显示视频
                        fullscreenButton.addEventListener('click', () => {
                            const videoContainer = document.querySelector('.video-container');
                            requestFullscreen(videoContainer);
                        });

                        // 退出全屏
                        exitFullscreenButton.addEventListener('click', () => {
                            exitFullscreen();
                        });

                        // 监听全屏状态变化
                        document.addEventListener('fullscreenchange', handleFullscreenChange);
                        document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
                        document.addEventListener('mozfullscreenchange', handleFullscreenChange);
                        document.addEventListener('MSFullscreenChange', handleFullscreenChange);
                    }

                    // 跨浏览器请求全屏
                    function requestFullscreen(element) {
                        try {
                            if (element.requestFullscreen) {
                                element.requestFullscreen();
                            } else if (element.webkitRequestFullscreen) {
                                element.webkitRequestFullscreen();
                            } else if (element.msRequestFullscreen) {
                                element.msRequestFullscreen();
                            } else if (element.mozRequestFullScreen) {
                                element.mozRequestFullScreen();
                            }
                            isFullscreen = true;
                            updateFullscreenButtons();
                        } catch (error) {
                            console.error('全屏请求失败:', error);
                            alert('无法进入全屏模式: ' + error.message);
                        }
                    }

                    // 跨浏览器退出全屏
                    function exitFullscreen() {
                        try {
                            if (document.exitFullscreen) {
                                document.exitFullscreen();
                            } else if (document.webkitExitFullscreen) {
                                document.webkitExitFullscreen();
                            } else if (document.msExitFullscreen) {
                                document.msExitFullscreen();
                            } else if (document.mozCancelFullScreen) {
                                document.mozCancelFullScreen();
                            }
                            isFullscreen = false;
                            updateFullscreenButtons();
                        } catch (error) {
                            console.error('退出全屏失败:', error);
                            alert('无法退出全屏模式: ' + error.message);
                        }
                    }

                    // 处理全屏状态变化
                    function handleFullscreenChange() {
                        // 检查实际全屏状态
                        const isActuallyFullscreen =
                            document.fullscreenElement ||
                            document.webkitFullscreenElement ||
                            document.mozFullScreenElement ||
                            document.msFullscreenElement;

                        isFullscreen = isActuallyFullscreen;
                        updateFullscreenButtons();
                    }

                    // 更新全屏按钮显示状态
                    function updateFullscreenButtons() {
                        const fullscreenButton = document.getElementById('fullscreen-video');
                        const exitFullscreenButton = document.getElementById('exit-fullscreen');

                        if (isFullscreen) {
                            fullscreenButton.classList.add('hidden');
                            exitFullscreenButton.classList.remove('hidden');
                        } else {
                            fullscreenButton.classList.remove('hidden');
                            exitFullscreenButton.classList.add('hidden');
                        }
                    }

                    // ====================== 机器人控制 ======================
                    function initRobotControl() {
                        const robot = {
                            element: document.getElementById('robot'),
                            commandDisplay: document.getElementById('current-command'),
                            gaitDisplay: document.getElementById('gait-mode'),
                            updateDisplay() {
                                this.element.style.left = `${esp32Data.robotStatus.position.x}%`;
                                this.element.style.top = `${esp32Data.robotStatus.position.y}%`;
                                this.element.style.transform = `rotate(${esp32Data.robotStatus.direction * 90}deg)`;
                                this.gaitDisplay.textContent = esp32Data.robotStatus.gait.charAt(0).toUpperCase() + esp32Data.robotStatus.gait.slice(1);
                            }
                        };

                        // 按键映射
                        const keyMappings = {
                            'w': 'btn-up',
                            's': 'btn-down',
                            'a': 'btn-left',
                            'd': 'btn-right'
                        };

                        // 移动机器人
                        function moveRobot(direction) {
                            const speed = 5;
                            const arena = document.querySelector('.robot-arena');
                            const arenaRect = arena.getBoundingClientRect();
                            const robotSize = robot.element.offsetWidth;
                            const maxX = 100 - (robotSize / arenaRect.width * 100);
                            const maxY = 100 - (robotSize / arenaRect.height * 100);

                            const prevX = esp32Data.robotStatus.position.x;
                            const prevY = esp32Data.robotStatus.position.y;

                            switch(direction) {
                                case 'up':
                                    esp32Data.robotStatus.position.y = Math.max(0, prevY - speed);
                                    esp32Data.robotStatus.direction = 0;
                                    break;
                                case 'down':
                                    esp32Data.robotStatus.position.y = Math.min(maxY, prevY + speed);
                                    esp32Data.robotStatus.direction = 2;
                                    break;
                                case 'left':
                                    esp32Data.robotStatus.position.x = Math.max(0, prevX - speed);
                                    esp32Data.robotStatus.direction = 3;
                                    break;
                                case 'right':
                                    esp32Data.robotStatus.position.x = Math.min(maxX, prevX + speed);
                                    esp32Data.robotStatus.direction = 1;
                                    break;
                            }

                            // 更新显示
                            robot.updateDisplay();

                            // 显示当前指令
                            robot.commandDisplay.textContent = direction;
                        }

                        // 步态切换
                        function switchGait(gaitType) {
                            const gaitButtons = document.querySelectorAll('#gait-wave, #gait-triangle');
                            gaitButtons.forEach(button => {
                                button.classList.remove('bg-control', 'text-white');
                                button.classList.add('bg-gray-200', 'text-gray-700');
                            });

                            const activeButton = document.getElementById(`gait-${gaitType}`);
                            if (activeButton) {
                                activeButton.classList.remove('bg-gray-200', 'text-gray-700');
                                activeButton.classList.add('bg-control', 'text-white');
                            }

                            esp32Data.robotStatus.gait = gaitType;
                            robot.updateDisplay();
                        }

                        // 高亮按键
                        function highlightKey(key) {
                            const btnId = keyMappings[key.toLowerCase()];
                            if (btnId) {
                                const btn = document.getElementById(btnId);
                                btn.classList.add('key-button-active');
                            }
                        }

                        // 取消高亮按键
                        function unhighlightKey(key) {
                            const btnId = keyMappings[key.toLowerCase()];
                            if (btnId) {
                                const btn = document.getElementById(btnId);
                                btn.classList.remove('key-button-active');
                            }
                        }

                        // 绑定按键事件
                        document.getElementById('btn-up').addEventListener('mousedown', () => {
                            highlightKey('w');
                            moveRobot('up');
                        });
                        document.getElementById('btn-down').addEventListener('mousedown', () => {
                            highlightKey('s');
                            moveRobot('down');
                        });
                        document.getElementById('btn-left').addEventListener('mousedown', () => {
                            highlightKey('a');
                            moveRobot('left');
                        });
                        document.getElementById('btn-right').addEventListener('mousedown', () => {
                            highlightKey('d');
                            moveRobot('right');
                        });

                        // 鼠标释放事件
                        document.addEventListener('mouseup', () => {
                            Object.keys(keyMappings).forEach(key => unhighlightKey(key));
                        });

                        // 键盘控制
                        document.addEventListener('keydown', (e) => {
                            const key = e.key.toLowerCase();
                            if (keyMappings[key]) {
                                e.preventDefault(); // 防止页面滚动
                                highlightKey(key);
                                moveRobot(key === 'w' ? 'up' : key === 's' ? 'down' : key === 'a' ? 'left' : 'right');
                            }
                        });

                        // 键盘释放事件
                        document.addEventListener('keyup', (e) => {
                            const key = e.key.toLowerCase();
                            if (keyMappings[key]) {
                                unhighlightKey(key);
                            }
                        });

                        // 绑定步态切换事件
                        document.getElementById('gait-wave').addEventListener('click', () => switchGait('wave'));
                        document.getElementById('gait-triangle').addEventListener('click', () => switchGait('triangle'));

                        // 初始化机器人显示
                        robot.updateDisplay();
                    }

                    // ====================== 传感器数据模拟 ======================
                    function initSensorDataSimulation() {
                        // 温度模拟
                        let temp = 25.6;
                        // 湿度模拟
                        let humidity = 48.2;
                        // 电池电压模拟
                        let batteryVoltage = 7.8;
                        // 电池温度模拟
                        let batteryTemp = 32.1;
                        // 开机时间（秒）
                        let uptimeSeconds = 9342;
                        // MCU占用
                        let MCUoccupy = 20;

                        // 每3秒更新一次传感器数据
                        setInterval(() => {
                            // 温度小幅波动
                            temp += (Math.random() - 0.5) * 0.4;
                            temp = Math.max(20, Math.min(35, temp));
                            document.getElementById('temp-value').textContent = temp.toFixed(1) + '°C';

                            // 湿度小幅波动
                            humidity += (Math.random() - 0.5) * 1.2;
                            humidity = Math.max(30, Math.min(70, humidity));
                            document.getElementById('humidity-value').textContent = humidity.toFixed(1) + '%';

                            // 电池电压小幅下降
                            batteryVoltage -= 0.001;
                            batteryVoltage = Math.max(7.0, batteryVoltage);
                            document.getElementById('battery-voltage').textContent = batteryVoltage.toFixed(1) + 'V';

                            // 电池温度小幅波动
                            batteryTemp += (Math.random() - 0.5) * 0.6;
                            batteryTemp = Math.max(30, Math.min(40, batteryTemp));
                            document.getElementById('battery-temp').textContent = batteryTemp.toFixed(1) + '°C';

                            // 更新开机时间
                            uptimeSeconds += 3;
                            const hours = Math.floor(uptimeSeconds / 3600).toString().padStart(2, '0');
                            const minutes = Math.floor((uptimeSeconds % 3600) / 60).toString().padStart(2, '0');
                            const seconds = (uptimeSeconds % 60).toString().padStart(2, '0');
                            document.getElementById('uptime-value').textContent = `${hours}:${minutes}:${seconds}`;

                            // MCU占用小波动
                            MCUoccupy += (Math.random() - 0.5) * 0.4;
                            MCUoccupy = Math.max(20, Math.min(100, MCUoccupy));
                            document.getElementById('MCUoccupy-value').textContent = MCUoccupy.toFixed(1) + '%';

                        }, 3000);
                    }

                    // ====================== 雷达点云图逻辑 ======================
                    let radarCanvas, radarCtx;
                    let radarRotation = 0;
                    let radarZoom = 1;
                    let radarCenterX = 200;
                    let radarCenterY = 150;
                    let radarRunning = true; // 控制雷达是否运行（扫描动画）

                    // 初始化雷达
                    function initRadar() {
                        radarCanvas = document.getElementById('radar-canvas');
                        radarCtx = radarCanvas.getContext('2d');

                        // 调整Canvas大小以匹配容器
                        resizeRadarCanvas();
                        window.addEventListener('resize', resizeRadarCanvas);

                        // 启动雷达动画
                        document.getElementById('radar-status').textContent = '状态: 扫描中...';
                        animateRadar();
                    }

                    // 调整雷达Canvas大小
                    function resizeRadarCanvas() {
                        const container = document.getElementById('radar-container');
                        radarCanvas.width = container.clientWidth;
                        radarCanvas.height = container.clientHeight;

                        // 更新雷达中心点
                        radarCenterX = radarCanvas.width / 2;
                        radarCenterY = radarCanvas.height / 2;

                        // 重新绘制雷达
                        drawRadar();
                    }

                    // 切换雷达运行状态
                    function toggleRadar() {
                        radarRunning = !radarRunning;
                        const btn = document.getElementById('toggle-radar');
                        if (btn) {
                            btn.innerHTML = radarRunning ? '<i class="fa fa-pause"></i>' : '<i class="fa fa-play"></i>';
                        }
                        document.getElementById('radar-status').textContent = `状态: ${radarRunning ? '扫描中...' : '已暂停'}`;

                        // 无论状态如何都重绘一次
                        drawRadar();
                    }

                    // 统一绘制函数
                    function drawRadar() {
                        // 清除画布
                        radarCtx.clearRect(0, 0, radarCanvas.width, radarCanvas.height);

                        // 绘制背景
                        drawRadarBackground();

                        // 绘制所有点（在静态版本中为空）
                        drawRadarPoints();

                        // 绘制雷达扫描线（动态或静态）
                        if (radarRunning) {
                            drawRadarScanLine();
                        } else {
                            drawStaticRadarScanLine();
                        }
                    }

                    // 雷达动画循环
                    function animateRadar() {
                        if (radarRunning) {
                            // 清除画布
                            radarCtx.clearRect(0, 0, radarCanvas.width, radarCanvas.height);

                            // 绘制背景
                            drawRadarBackground();

                            // 绘制所有点（在静态版本中为空）
                            drawRadarPoints();

                            // 绘制雷达扫描线
                            drawRadarScanLine();

                            // 更新雷达旋转角度
                            radarRotation += 0.03;
                            if (radarRotation > Math.PI * 2) {
                                radarRotation -= Math.PI * 2;
                            }

                            requestAnimationFrame(animateRadar);
                        }
                    }

                    // 绘制雷达背景
                    function drawRadarBackground() {
                        // 绘制背景黑色
                        radarCtx.clearRect(0, 0, radarCanvas.width, radarCanvas.height);
                        radarCtx.fillStyle = '#000';
                        radarCtx.fillRect(0, 0, radarCanvas.width, radarCanvas.height);

                        // 绘制雷达圆圈
                        radarCtx.strokeStyle = 'rgb(255,255,255)';
                        radarCtx.lineWidth = 2;

                        // 绘制多个同心圆
                        const maxRadius = Math.min(radarCanvas.width, radarCanvas.height) * 0.45;
                        for (let i = 1; i <= 5; i++) {
                            const radius = (maxRadius / 5) * i;
                            radarCtx.beginPath();
                            radarCtx.arc(radarCenterX, radarCenterY, radius / radarZoom, 0, Math.PI * 2);
                            radarCtx.stroke();
                        }

                        // 绘制十字线
                        radarCtx.beginPath();
                        radarCtx.moveTo(radarCenterX - maxRadius / radarZoom, radarCenterY);
                        radarCtx.lineTo(radarCenterX + maxRadius / radarZoom, radarCenterY);
                        radarCtx.moveTo(radarCenterX, radarCenterY - maxRadius / radarZoom);
                        radarCtx.lineTo(radarCenterX, radarCenterY + maxRadius / radarZoom);
                        radarCtx.stroke();

                        // 绘制距离标记
                        radarCtx.fillStyle = 'rgb(255,255,255)';
                        radarCtx.font = '10px monospace';

                        for (let i = 1; i <= 5; i++) {
                            const radius = (maxRadius / 5) * i;
                            const text = `${i * 50}`;
                            const textWidth = radarCtx.measureText(text).width;

                            radarCtx.fillText(text, radarCenterX + radius / radarZoom - textWidth - 5, radarCenterY - 5);
                        }
                    }

                    // 绘制雷达点（在静态版本中为空）
                    function drawRadarPoints() {
                        // 静态版本不绘制任何点（无障碍环境）
                    }

                    // 绘制静态雷达扫描线
                    function drawStaticRadarScanLine() {
                        const maxRadius = Math.min(radarCanvas.width, radarCanvas.height) * 0.45;
                        const staticAngle = Math.PI / 4; // 固定扫描线角度

                        // 绘制扫描线
                        radarCtx.strokeStyle = 'rgb(255,255,255)';
                        radarCtx.lineWidth = 2;
                        radarCtx.beginPath();
                        radarCtx.moveTo(radarCenterX, radarCenterY);
                        radarCtx.lineTo(
                            radarCenterX + Math.cos(staticAngle) * maxRadius / radarZoom,
                            radarCenterY + Math.sin(staticAngle) * maxRadius / radarZoom
                        );
                        radarCtx.stroke();

                        // 绘制扇形扫描区域
                        const gradient = radarCtx.createRadialGradient(
                            radarCenterX, radarCenterY, 0,
                            radarCenterX, radarCenterY, maxRadius / radarZoom
                        );

                        gradient.addColorStop(0, 'rgba(0, 255, 0, 0.05)');
                        gradient.addColorStop(1, 'rgba(0, 255, 0, 0)');

                        radarCtx.fillStyle = gradient;
                        radarCtx.beginPath();
                        radarCtx.moveTo(radarCenterX, radarCenterY);
                        radarCtx.arc(radarCenterX, radarCenterY, maxRadius / radarZoom, staticAngle - 0.3, staticAngle);
                        radarCtx.closePath();
                        radarCtx.fill();
                    }

                    // 绘制动态雷达扫描线
                    function drawRadarScanLine() {
                        const maxRadius = Math.min(radarCanvas.width, radarCanvas.height) * 0.45;

                        // 绘制扫描线
                        radarCtx.strokeStyle = 'rgb(255,255,255)';
                        radarCtx.lineWidth = 2;
                        radarCtx.beginPath();
                        radarCtx.moveTo(radarCenterX, radarCenterY);
                        radarCtx.lineTo(
                            radarCenterX + Math.cos(radarRotation) * maxRadius / radarZoom,
                            radarCenterY + Math.sin(radarRotation) * maxRadius / radarZoom
                        );
                        radarCtx.stroke();

                        // 绘制扇形扫描区域
                        const gradient = radarCtx.createRadialGradient(
                            radarCenterX, radarCenterY, 0,
                            radarCenterX, radarCenterY, maxRadius / radarZoom
                        );

                        gradient.addColorStop(0, 'rgba(0, 255, 0, 0.05)');
                        gradient.addColorStop(1, 'rgba(0, 255, 0, 0)');

                        radarCtx.fillStyle = gradient;
                        radarCtx.beginPath();
                        radarCtx.moveTo(radarCenterX, radarCenterY);
                        radarCtx.arc(radarCenterX, radarCenterY, maxRadius / radarZoom, radarRotation - 0.3, radarRotation);
                        radarCtx.closePath();
                        radarCtx.fill();
                    }
                </script>
            </body>
            </html>
            """
    
    # 主服务循环
    while True:
        try:
            cl, addr = server_socket.accept()
            print(f'客户端连接来自: {addr}')
            
            # 接收请求
            request = cl.recv(1024)
            
            # 发送响应
            cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
            cl.send(html)
            cl.close()
            
        except Exception as e:
            print(f"服务器异常: {e}")
            if 'cl' in locals():
                cl.close()
